// 需要提供外部时钟
// 需要将RAM的写操作暴露给外部
// 该模块只有输入没有输出
// 该模块需要组织RAM、ROM和TFT
module vision_ctrl_test(
	Clk, 	//50MHZ时钟
	Rst_n,
	TFT_RGB,//TFT数据输出
	TFT_HS,	//TFT行同步信号
	TFT_VS,	//TFT场同步信号
	TFT_CLK,
	TFT_DE,
	TFT_PWM
	// RAM 写
	// ram_wren,
	// ram_wraddress,
	// ram_input,
	// TFT 输出
);
	// 输入输出
	input Clk;
	input Rst_n;
	reg ram_wren;
	reg [11:0] ram_wraddress;
	reg [7:0] ram_input;
	
	// TFT
	output TFT_HS;           //TFT行同步信号
	output TFT_VS;           //TFT场同步信号
	output TFT_DE;		//TFT 场消隐信号
	output TFT_CLK;		//TFT DAC输出时钟
	output TFT_PWM;
	output [15:0]TFT_RGB;  //TFT数据输出
	
	// clk
	wire Clk_r = ~Clk;
	
	// RAM
	reg[11:0] ram_rdaddress;
	wire[7:0] ram_output;
	
	// ROM
	reg [7:0]rom_address;
	wire [127:0]rom_output; 

	// TFT
	wire  [11:0]hcount;
	wire  [11:0]vcount;
	// TFT延时寄存器
	reg  [11:0]hcount_1;
	reg  [11:0]vcount_1;
	reg  [11:0]hcount_2;
	reg  [11:0]vcount_2;
	reg  [11:0]hcount_3;
	reg  [11:0]vcount_3;
	reg  [11:0]hcount_4;
	reg  [11:0]vcount_4;
	//TFT暂存显示数据
	reg [15:0]disp_data;

	
	
	ram ram_instance0(
		.clock(Clk_r),
		.wren(ram_wren),
		.data(ram_input),
		.wraddress(ram_wraddress),
		.rdaddress(ram_rdaddress),
		.q(ram_output)
	);
	
	rom rom_instance0(
		.clock(Clk_r),
		.address(rom_address),
		.q(rom_output)
	);
	
	
	
	tft_ctrl tft_ctrl_instance0(
		.Clk33M(Clk),
		.Rst_n(Rst_n),
		// .Data_in(disp_data),
		.Hcount(hcount),
		.Vcount(vcount),
		// .TFT_rgb(TFT_RGB),
		.TFT_hs(TFT_HS),
		.TFT_vs(TFT_VS),
		.TFT_clk(TFT_CLK),
		.TFT_de(TFT_DE),
		.TFT_pwm(TFT_PWM)
	);
	
	
	/************************************** 
		1. 根据tft扫描位置计算RAM位置 
		2. 读取RAM的数值
		3. 将读取RAM的数值作为地址读取ROM
		4. 将ROM读取的数值取需要位渲染
		5. TFT信号的同步
	*************************************/	
	reg [11:0]tft_logic_pos;
	
	// 1. 计算RAM位置
	always @(posedge Clk)
	begin
		tft_logic_pos <= ((vcount >> 4) * 80 + ((hcount-80) >> 3));
	end 
	
	// 2. 读取RAM位置的数值 !todo 时钟
	always @(posedge Clk)
	begin
		ram_rdaddress <= tft_logic_pos;
	end
	
	// 3. 将读取RAM的数值作为地址读取ROM
	always @(posedge Clk)
	begin 
		rom_address <= ram_output;
	end
	
	// 4. 将ROM读取的数值取需要位渲染
	reg [8:0]pixel_index;
	always @(posedge Clk)
	begin 
		if (hcount_ack)
			pixel_index <= ((vcount_4[3:0] << 3) + 7 - hcount_4[2:0]);
	end	

	// 5. 渲染数据读取到寄存器里面
	wire hcount_ack = hcount_4 >= 80 && hcount_4 < 720;
	always @(posedge Clk)
	begin 
		if (!hcount_ack)
			disp_data <= 16'b0000_0000_0000_0000;
		else
			begin
				if (rom_output[pixel_index] == 1'b1)
					disp_data <= 16'b1111_1111_1111_1111;
				else
					disp_data <= 16'b0000_0000_0000_0000;
			end
	end
	
	assign TFT_RGB = disp_data;
	
	// 5. TFT信号的同步
	always @(posedge Clk)
	begin 
		 hcount_1  <=  hcount;
		 vcount_1  <=  vcount;		
	end
	
	always @(posedge Clk)
	begin 
		 hcount_2  <=  hcount_1;
		 vcount_2  <=  vcount_1;	
	end
	
	always @(posedge Clk)
	begin 
		 hcount_3  <=  hcount_2;
		 vcount_3  <=  vcount_2;	
	end
	
	always @(posedge Clk)
	begin 
		 hcount_4  <=  hcount_3;
		 vcount_4  <=  vcount_3;	
	end
	
	
endmodule
